In the program example discussed in the previous post (multiple catch blocks section), we made a URL connection to read the home page contents from the user-specified URL. We closed this connection by calling the close method on the stream object.
Now, consider some slightly low-level code that makes a socket connection to another machine on the network and reads/writes data using this socket. During this entire communication, if an exception occurs, our exception handler handles the exception. If the communication was successful, our program would usually close the socket before proceeding with the next program statement. However, the socket closing is required even if an exception occurs at runtime. For example, even though we may be able to make a successful socket connection, an exception might occur during the read/write operations. Obviously, the socket needs to be closed in this case too. To take care of such situations, Java provides a construct called finally. The finally block does this trick. We execute the socket-close operation in the finally block. The structure of a finally block is illustrated here:
Try-catch-finally block program flow:
And the syntax of the complete try/catch/finally block is as shown here:
try {
blockStatementsopt
} catch ( ExceptionType exceptionObjectName ) {
blockStatements
}
finally {
blockStatements
}
Typical try/catch/finally code is shown here:
try {
// code that may generate a runtime exception
} catch (SubclassException e1) {
// your error handler
} catch (SubclassException e2) {
// your error handler
} catch (Exception e) {
// your error handler
} finally {
// this code is always executed
}
The code to be tested is enclosed in the try block. If an exception occurs during execution, an appropriate exception handler is called. After the exception is processed, the program calls the finally block and executes the code in it. What happens if we have not provided the handler for the type of exception that occurs in the running program? The code in the finally block still executes. What happens if the code under test does not generate an exception? In this case, too, the code in the finally block is called and executed. It means that the finally block code is always executed.
From this discussion, we can see that the ideal place for closing the socket connection would be the finally block. By placing the socket- or stream-close code in the finally block, we ensure that the socket or stream is always closed regardless of communication success or failure. A finally block is typically useful for clean-up code or any mess created in the try block, especially when recovering resources in use.
Sushant Mishra
14-Apr-2017